﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace RepositoryFramework
{
	/// <summary>
	/// Class <see cref="FilterExtensions"/> define extensions to filter obejct
	/// </summary>
	public static class FilterExtensions
	{
		/// <summary>
		/// Gets the SQL parameters.
		/// </summary>
		/// <typeparam name="T"</typeparam>
		/// <param name="filter">The filter.</param>
		/// <returns>list of pairs<name, value></returns>
		public static IEnumerable<NameValue<string, object>> GetSqlParameters<T>(this T filter) where T : IBaseFilter
		{
			List<NameValue<string, object>> result = new List<NameValue<string, object>>();

			if (filter != null)
			{
				PropertyInfo[] props = typeof(T).GetProperties();
				foreach (PropertyInfo prop in props)
				{
					var set = GetParameter(filter, prop);
					if (set != null)
					{
						result.Add(set);
					}
				}
			}
			return result;
		}

		private static NameValue<string, object> GetParameter<T>(T filter, PropertyInfo prop) where T : IBaseFilter
		{
			object[] attrs = prop.GetCustomAttributes(true);
			foreach (object attr in attrs)
			{
				var attribute = attr as SqlParameterAttribute;
				if (attribute != null)
				{
					var set = new NameValue<string, object>(attribute.Name, filter.GetPropertyValue(prop.Name));
					return set;
				}
			}
			return null;
		}

		private static T GetPropertyValue<T>(this T filter, string property) where T : IBaseFilter
		{
			if (filter == null)
			{
				throw new ArgumentNullException("filter");
			}

			var sourceType = filter.GetType();
			var sourceProperties = sourceType.GetProperties();

			var propertyValue = (from s in sourceProperties
								 where s.Name.Equals(property)
								 select s.GetValue(filter, null)).FirstOrDefault();

			return propertyValue != null ? (T)propertyValue : default(T);
		}
	}
}
